package com.szewec.ps.util.imagepicker;

import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.szewec.ps.R;
import com.szewec.ps.myview.toast.ToastUtils;
import com.szewec.ps.util.PreferincesContext;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class MedioRecorderCamera1Activity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MedioRecorderCamera1Activity.class.getSimpleName();
    private TextureView mTextureview;
    private MediaRecorder mMediaRecorder = new MediaRecorder();
    private Camera mCamera;
    private Camera.Size mSelectSize;//记录当前选择的分辨率
    private boolean isRecorder = false;//用于判断当前是否在录制视频
    private String mFilePath;
    private ImageView video_btn;
    //计时器
    private Handler mhandle = new Handler();
    private boolean isPause = false;//是否暂停
    private long currentSecond = 0;//当前毫秒数
    private TextView mtvTime;

    private ImageView iv_flash_video;
    private ImageView iv_change_camera;
    private boolean isFlashOpen;
    private boolean isFront = false;
    private int MaxTime = 60 * 60 * 1000;

    /*****************计时器*******************/
    private Runnable timeRunable = new Runnable() {
        @Override
        public void run() {
            currentSecond = currentSecond + 1000;
            mtvTime.setText(getFormatHMS(currentSecond));
            if (!isPause) {
                //递归调用本runable对象，实现每隔一秒一次执行任务
                mhandle.postDelayed(this, 1000);
            }
            //到时候了自动关闭
            if (currentSecond == MaxTime) {
                isRecorder = !isRecorder;
                if (!isRecorder) {
                    //自动暂停
                    video_btn.setBackgroundResource(R.drawable.video_default1);
                    stopRecorder();
                }
            }
        }
    };
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0x01:
                    mCamera.autoFocus(new Camera.AutoFocusCallback() { //自动对焦
                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {

                        }
                    });
                    mHandler.sendEmptyMessageDelayed(0x01, 3 * 1000);//3秒之后在对焦一次,一直重复自动对焦
                    break;
                default:
                    break;
            }
        }
    };

    /**
     * 根据毫秒返回时分秒
     *
     * @param time
     * @return
     */
    public String getFormatHMS(long time) {
        time = time / 1000;//总秒数
        int s = (int) (time % 60);//秒
        int m = (int) (time / 60) % 60;//分
        int h = (int) (time / 3600) % 60;//小时
        return String.format("%02d:%02d:%02d", h, m, s);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_medio_recorder_camera);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//        if (Build.VERSION.SDK_INT >= 23) {
//            int REQUEST_CODE_CONTACT = 101;
//            String[] permissions = {Manifest.permission.RECORD_AUDIO,
//                    Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
//            //验证是否许可权限
//            for (String str : permissions) {
//                if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
//                    //申请权限
//                    this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
//                    return;
//                }
//            }
//        }
        iv_flash_video = findViewById(com.zhaoss.weixinrecorded.R.id.iv_flash_video);
        iv_change_camera = findViewById(com.zhaoss.weixinrecorded.R.id.iv_camera_mode);
        mtvTime = findViewById(R.id.tv_time);
        mTextureview = findViewById(R.id.textureview);
        video_btn = findViewById(R.id.video_btn);
        video_btn.setOnClickListener(this);
        findViewById(R.id.iv_delete).setOnClickListener(this);
        initTextureViewListener();
        initMediaRecorder();
        iv_flash_video.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeFlash();
                if (isFlashOpen) {
                    iv_flash_video.setImageResource(com.zhaoss.weixinrecorded.R.mipmap.video_flash_open);
                } else {
                    iv_flash_video.setImageResource(com.zhaoss.weixinrecorded.R.mipmap.video_flash_close);
                }
            }
        });

        iv_change_camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isFront = !isFront;
                mCamera = Camera.open(selectCamera(isFront));//切换
                mCamera.unlock();
                mMediaRecorder.setCamera(mCamera);
                iv_flash_video.setImageResource(com.zhaoss.weixinrecorded.R.mipmap.video_flash_close);
            }
        });

    }

    /**
     * 初始化TextureView监听
     */
    private void initTextureViewListener() {
        mTextureview.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { //Textureview初始化启用回调
                initCamera();
                initCameraConfig();
                try {
                    mCamera.setPreviewTexture(surface);
                    mCamera.startPreview();
                    mHandler.sendEmptyMessage(0x01);//启动对焦
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.video_btn:
                isRecorder = !isRecorder;
                if (isRecorder) {
                    //录制中
                    startRecorder();
                    video_btn.setBackgroundResource(R.drawable.video_starting1);
                } else {
                    //暂停
                    stopRecorder();
                    video_btn.setBackgroundResource(R.drawable.video_default1);
                }
                break;
            case R.id.iv_delete:
                finish();
                break;

            default:
                break;
        }

    }

    /**
     * 初始化MediaRecorder
     */
    private void initMediaRecorder() {
        if(mMediaRecorder == null){
            mMediaRecorder = new MediaRecorder();
        }
    }

    /**
     * 选择摄像头
     *
     * @param isFacing true=前摄像头 false=后摄像头
     * @return 摄像id
     */
    private Integer selectCamera(boolean isFacing) {
        int cameraCount = Camera.getNumberOfCameras();
//        CameraInfo.CAMERA_FACING_BACK 后摄像头
//        CameraInfo.CAMERA_FACING_FRONT  前摄像头
        int facing = isFacing ? Camera.CameraInfo.CAMERA_FACING_FRONT : Camera.CameraInfo.CAMERA_FACING_BACK;
        Log.e(TAG, "selectCamera: cameraCount=" + cameraCount);
        if (cameraCount == 0) {
            Log.e(TAG, "selectCamera: The device does not have a camera ");
            return null;
        }
        Camera.CameraInfo info = new Camera.CameraInfo();
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, info);
            if (info.facing == facing) {
                return i;
            }

        }
        return null;

    }

    public void changeFlash() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            String flashMode = parameters.getFlashMode();
            List<String> flashModeList = parameters.getSupportedFlashModes();
            if (!isFlashOpen) {
                if (flashModeList != null && flashModeList.contains("torch") && !"torch".equals(flashMode)) {
                    try {
                        parameters.setFlashMode("torch");
                        mCamera.setParameters(parameters);
                        isFlashOpen = true;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } else {
                if (flashModeList != null && flashModeList.contains("off") && !"off".equals(flashMode)) {
                    try {
                        parameters.setFlashMode("off");
                        mCamera.setParameters(parameters);
                        isFlashOpen = false;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 初始化相机
     */
    private void initCamera() {
        mCamera = Camera.open(selectCamera(isFront));
//        mSelectSize = selectPreviewSize(mCamera.getParameters());


    }

    /**
     * 初始化相机配置
     */
    private void initCameraConfig() {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);//关闭闪光灯
        parameters.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO); //对焦设置为自动

        int[] size = selectPreviewSize(mCamera.getParameters());
        parameters.setPreviewSize(size[0], size[1]);//设置预览尺寸
//        parameters.setPictureSize(mSelectSize.width, mSelectSize.height);//设置图片尺寸  就拿预览尺寸作为图片尺寸,其实他们基本上是一样的(这个会导致部分手机设置setParameters报错)
        parameters.set("orientation", "portrait");//相片方向
        parameters.set("rotation", 90); //相片镜头角度转90度（默认摄像头是横拍）
        mCamera.setDisplayOrientation(90);//设置显示方向
        try {
            mCamera.setParameters(parameters);//添加参数
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * 计算获取预览尺寸
     *
     * @param parameters
     * @return
     */
    private int[] selectPreviewSize(Camera.Parameters parameters) {
        List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
        if (previewSizeList.size() == 0) {
            Log.e(TAG, "selectPreviewSize: previewSizeList size is 0");
            return null;

        }
        Camera.Size currentSelectSize = null;
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int deviceWidth = displayMetrics.widthPixels;
        int deviceHeight = displayMetrics.heightPixels;

        int[] a = new int[previewSizeList.size()];
        int[] b = new int[previewSizeList.size()];
        for(int i=0 ;i<previewSizeList.size();i++){
            int supportH = previewSizeList.get(i).height;
            int supportW = previewSizeList.get(i).width;
            a[i] = Math.abs(supportW - deviceWidth);
            b[i] = Math.abs(supportH - deviceWidth);
        }

        int minW=0,minA=a[0];
        for( int i=0; i<a.length; i++){
            if(a[i]<=minA){
                minW=i;
                minA=a[i];
            }
        }
        int minH=0,minB=b[0];
        for( int i=0; i<b.length; i++){
            if(b[i]<minB){
                minH=i;
                minB=b[i];
            }
        }
        return new int[]{previewSizeList.get(minW).width,previewSizeList.get(minH).height};
    }

    /**
     * 配置MedioRecorder
     */
    private void configMedioRecorder() {
        File fileDir = new File(Environment.getExternalStorageDirectory(), "Video");
        if (!fileDir.exists()) {
            fileDir.mkdir();
        }
        mFilePath = fileDir.getAbsolutePath() + "/VID_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4";
        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);
        Surface surface = new Surface(mTextureview.getSurfaceTexture());
        mMediaRecorder.setPreviewDisplay(surface);//设置预览
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置音频源
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);//设置视频源
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置音频输出格式
        mMediaRecorder.setAudioEncodingBitRate(3600);
        mMediaRecorder.setAudioChannels(1);
        mMediaRecorder.setCaptureRate(15);
        mMediaRecorder.setAudioSamplingRate(4000);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//设置音频编码格式AAC,
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码格式
//        mMediaRecorder.setVideoSize(320, 240);//设置视频分辨率
        mMediaRecorder.setVideoSize(1280, 720);//设置视频分辨率
//        mMediaRecorder.setVideoEncodingBitRate(1 * 800 * 600);//设置视频的比特率
//        mMediaRecorder.setVideoEncodingBitRate(900*512);//设置视频的比特率
        mMediaRecorder.setVideoEncodingBitRate(320 * 240 * 3);//设置视频的比特率
//        mMediaRecorder.setVideoEncodingBitRate(550000);//设置视频的比特率 2.32M
//        mMediaRecorder.setVideoEncodingBitRate(400000);//设置视频的比特率

        mMediaRecorder.setVideoFrameRate(30);//设置视频的帧率
//        mMediaRecorder.setVideoFrameRate(60);//设置视频的帧率
        mMediaRecorder.setOrientationHint(90);//设置视频的角度
        mMediaRecorder.setMaxDuration(MaxTime);//设置最大录制时间

        mMediaRecorder.setOutputFile(mFilePath);//设置文件保存路径
        mMediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { //录制异常监听
            @Override
            public void onError(MediaRecorder mr, int what, int extra) {
                mMediaRecorder.stop();
                mMediaRecorder.reset();
                try {
                    mCamera.setPreviewTexture(mTextureview.getSurfaceTexture());
                    mCamera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });

    }

    /**
     * 开启录制视频
     */
    private void startRecorder() {
        mtvTime.setVisibility(View.VISIBLE);
        timeRunable.run();//开始计时
//        mCamera.stopPreview();//暂停相机预览
        configMedioRecorder();//再次配置MedioRecorder
        try {
            mMediaRecorder.prepare();//准备录制
        } catch (IOException e) {
            e.printStackTrace();
        }
        mMediaRecorder.start();//开始录制
    }

    /**
     * 停止录制视频
     */
    private void stopRecorder() {
        ToastUtils.getInstanc(MedioRecorderCamera1Activity.this).showToast("录制结束,请继续", Toast.LENGTH_SHORT);
        mtvTime.setVisibility(View.GONE);
        mhandle.removeCallbacks(timeRunable);
        mMediaRecorder.stop();//暂停录制
        mMediaRecorder.reset();//重置,将MediaRecorder调整为空闲状态
        try {
            mCamera.setPreviewTexture(mTextureview.getSurfaceTexture());//重新设置预览SurfaceTexture
            mCamera.startPreview(); //重新开启相机预览
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

        Intent intent = new Intent();
        intent.putExtra(PreferincesContext.FILEPATH, mFilePath);
        setResult(RESULT_OK, intent);
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mhandle.removeCallbacks(timeRunable);
        if (mMediaRecorder != null) {
            if (isRecorder) {
                mMediaRecorder.stop();
            }
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }

        mHandler.removeCallbacksAndMessages(null);
    }
}